﻿using System;

using Phidgets;

namespace Coding4Fun.BoxingBots.Robot
{
	public class LedController: IDisposable
	{
		private readonly LED _phidgetLed;

		private const int TotalHealth = 8;
		private const int LedsPerHealth = 3;

		private const int LedOffsetHealth = 0;
		private const int LedOffsetEyesDead = 32;
		private const int LedOffsetEyesAlive1 = 48;
		private const int LedOffsetEyesAlive2 = 24;
		private const int LedOffsetEyesAlive3 = 28;

		private int _currentHealth;

		internal LedController() { }

		internal LedController(LED phidgetLed) : this()
		{
			_phidgetLed = phidgetLed;

			_phidgetLed.Voltage = LED.LEDVoltage.VOLTAGE_3_9V;
        }

		public void ResetHealt()
		{
			SetHealth(TotalHealth);
		}

		public void SetHealth(int value)
		{
			_currentHealth = value;

			// TODO: abstract into animation loop for pulsing
            if (_currentHealth < 0)
                _currentHealth = -TotalHealth;

			var blackLedAmount = (TotalHealth - _currentHealth) * LedsPerHealth;
			var redLedAmount = _currentHealth * LedsPerHealth;

			UpdateLedsNonSuperBright(blackLedAmount, LedOffsetHealth, 0);
			UpdateLedsNonSuperBright(redLedAmount, LedOffsetHealth + blackLedAmount, 100);

			if (value <= 0)
				DisplayDead();
			else
				DisplayAlive();
		}

		public void DisplayAlive()
		{
			UpdateEyesDead(0);
			UpdateEyesAlive(100);
		}

		public void DisplayDead()
		{
			UpdateEyesDead(100);
			UpdateEyesAlive(0);
		}

		private void UpdateEyesDead(int brightness)
		{
			UpdateLedsNonSuperBright(16, LedOffsetEyesDead, brightness);
		}

		private void UpdateEyesAlive(int brightness)
		{
			UpdateLedsNonSuperBright(16, LedOffsetEyesAlive1, brightness);
			UpdateLedsSuperBright(4, LedOffsetEyesAlive2, brightness);
			UpdateLedsNonSuperBright(4, LedOffsetEyesAlive3, brightness);
		}

		private void UpdateLedsNonSuperBright(int amount, int offset, int brightness)
		{
			for (var i = offset; i < amount + offset; i++)
			{
				_phidgetLed.leds[i] = brightness / 2;
			}
		}

		private void UpdateLedsSuperBright(int amount, int offset, int brightness)
		{
			for (var i = offset; i < amount + offset; i++)
			{
				_phidgetLed.leds[i] = brightness;
			}
		}

		public bool IsConnected
		{
			get { return (_phidgetLed != null && _phidgetLed.Attached); }
		}

		public void Dispose()
		{
			
		}
	}
}
